package com.dtx.flyweight;

import java.util.HashMap;
import java.util.Map;

/**
 * BigFactory类是生成BigChar类的实例的工厂(factory)。它实现了共享实例的功能。
 * pool字段用于管理已经生成的BigChar类的实例。Pool有泳池的意思。现在任何存放某些东西的地方
 * 都可以被叫作Pool。泳池存储的是水,而BigCharFactory的pool中存储的则是已经生成的BigChar类的实例。
 * 在BigCharFactory类中,我们使用java.util.HashMap类来管理"字符串→实例"之间的对应关系。使用
 * java.util.HashMap类的put方法可以将某个字符串(键)与一个实例(值)关联起来。之后,就可以通过键来获取它
 * 相应的值。在示例程序中.我们将接收到的单个字符(例如'3')作为键与表示3的BigChar的类的实例对应起来。
 * 我们使用了Singleton模式来实现BigCharFactory类,这是因为我们只需要一个BigCharFactory类的实例就可以了。
 * getInstance方法用于获取BigCharFactory类的实例(注意不是BigChar类的实例哟)。
 * getBigChar方法是Flyweight模式的核心方法。该方法会生成接收到的字符所对应的BigChar类的实例。不过,如果它发现字符
 * 所对应的实例已经存在,就不会再生成新的实例,而是将之前的那个实例返回给调用者。
 * 请仔细理解这段逻辑。该方法首先会通过pool.get()方法查找,以调查是否存在接收到字符(charName)所对应的BigChar类的实例。
 * 如果返回值为null,表示目前为止还没有创建该实例,于是它会通过new BigChar(charName);来生成实例,并通过pool.put将该实例
 * 放入HashMap中。如果返回值不为null,则会将之前生成的实例返回给调用者。
 * 我们通过这种方式实现了共享BigChar类的实例。
 */
public class BigCharFactory {

    //管理已经生成的BigChar的实例
    private Map<String,Object> pool = new HashMap<>();

    //Singleton模式
    private static BigCharFactory singleton = new BigCharFactory();

    //构造函数
    private BigCharFactory(){}

    /**
     * 获取唯一的实例
     * @return
     */
    public static BigCharFactory getInstance(){
        return singleton;
    }

    public synchronized BigChar getBigChar(char charName){
        BigChar bc = (BigChar) pool.get("" + charName);
        if (bc == null) {
            //生成BigChar的实例
            bc = new BigChar(charName);
            pool.put(""+charName,bc);
        }
        return bc;
    }
}
